﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CommonFunction
{
    public class RandomHelper : RandomInterface
    {
        #region 生成完全随机字符串
        
        public string GetRandomString(int length, bool useLow = true, bool useUpp = false, bool useNum = false, bool useSpe = false, string custom = "")
        {
            byte[] b = new byte[4];
            new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(b);
            Random r = new Random(BitConverter.ToInt32(b, 0));
            string s = null, str = custom;
            if (useNum == true) { str += "0123456789"; }
            if (useLow == true) { str += "abcdefghijklmnopqrstuvwxyz"; }
            if (useUpp == true) { str += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
            if (useSpe == true) { str += "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; }
            for (int i = 0; i < length; i++)
            {
                s += str.Substring(r.Next(0, str.Length - 1), 1);
            }
            return s;
        }
        #endregion
        #region 生成根据当前时间计算出的字符串
        
        public string GetTimeString()
        {
            string scString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            char[] sc = scString.ToCharArray();
            DateTime startTime = new DateTime(2000, 1, 1, 0, 0, 0, 0);
            long prve = 0;

            lock (_lock)
            {
                TimeSpan ts = DateTime.UtcNow - startTime; //时间戳保证即使应用程序重启依然不会重复
                long temp = Convert.ToInt64(ts.TotalMilliseconds * 10);  //毫秒1000*10保证一秒最多9999可增长
                if (temp > prve)
                {
                    prve = temp;
                    return ToShortString(temp, sc);
                }
                else
                {
                    prve++;
                    return ToShortString(prve, sc);
                }
            }
                
        }

        static readonly object _lock = new object();
        /// <summary>
        /// 通过进制机制将数字转成更短的字符串
        /// </summary>
        private string ToShortString(long num,char[] sc)
        {
            string str = "";
            while (num >= sc.Length)
            {
                str = sc[num % sc.Length] + str;
                num = num / sc.Length;
            }
            return sc[num] + str;
        }


        #endregion
    }

    interface RandomInterface
    {
        ///<summary>
        ///生成随机字符串 
        ///</summary>
        ///<param name="length">目标字符串的长度</param>
        ///<param name="useLow">是否包含小写字母，1=包含，默认为包含</param>
        ///<param name="useUpp">是否包含大写字母，1=包含，默认为包含</param>
        ///<param name="useNum">是否包含数字，1=包含，默认为包含</param>
        ///<param name="useSpe">是否包含特殊字符，1=包含，默认为不包含</param>
        ///<param name="custom">要包含的自定义字符，直接输入要包含的字符列表</param>
        ///<returns>指定长度的随机字符串</returns>
        string GetRandomString(int length, bool useLow, bool useUpp, bool useNum,  bool useSpe, string custom);

        /// <summary>
        /// 生成根据当前时间计算出的字符串
        /// </summary>
        /// <returns></returns>
        string GetTimeString();
    }
}
